from threading import Thread, Lock
from multiprocessing import cpu_count
from queue import Queue

maxJobThreads = min(cpu_count(), 8)
class MutiThreadJobs:
    def __init__(self, threads : int = maxJobThreads):
        class EndJob:
            pass
        self._endJob = EndJob()
        self._threadsCount = threads
        self._threads = []
        self._jobs = Queue()

    def addJobs(self, jobs):
        if type(jobs) is list:
            for job in jobs:
                self._jobs.put(job)
        else:
            self._jobs.put(jobs)

    def stop(self):
        for x in range(0, self._threadsCount):
            self.addJobs(self._endJob)
    
    def run(self):
        while True:
            job = self._jobs.get()
            if job == self._endJob:
                break
            try:
                import traceback
                print("==============================================================")
                print("start job:", job)
                print("==============================================================")
                job()
            except:
                import traceback
                print("==============================================================")
                print("=========================job exception========================")
                print("==============================================================")
                print(traceback.format_exc())


    def start(self):
        for x in range(0, self._threadsCount):
            t = Thread(target=self.run)
            self._threads.append(t)
        for t in self._threads:
            t.start()

    def join(self):
        self.stop()
        for t in self._threads:
            t.join()
